package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.api.feign.ApArticleFeignClient;
import com.heima.audit.baidu.BaiduImageScan;
import com.heima.audit.baidu.BaiduTextScan;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmAutoScanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WmAutoScanServiceImpl implements WmAutoScanService {

  @Autowired
  private WmNewsMapper wmNewsMapper;

  @Autowired
  private BaiduTextScan baiduTextScan;

  @Autowired
  private BaiduImageScan baiduImageScan;

  @Autowired
  private FileStorageService fileStorageService;

  @Autowired
  private ApArticleFeignClient apArticleFeignClient;

  @Autowired
  private WmUserMapper wmUserMapper;

  @Autowired
  private WmChannelMapper wmChannelMapper;

  /**
   * 审核自媒体文章
   *主方法
   * @param newsId 自媒体文章id
   */
  @Override
  @Transactional
  public void autoScanWmNews(Integer newsId) {
    //1.非空判断
    if(newsId==null){
      return;
    }
    //2.查询自媒体文章实体
    WmNews wmNews = wmNewsMapper.selectById(newsId);
    if(wmNews==null){
      return;
    }
    //2.5 先抽取所有的文本和图片
    Map<String, Object> resultMap = handleTextAndImages(wmNews);

    /**
     * 3.文本审核-百度云审核
     * status=1 合规
     * status=2 不合规
     * status=3 疑似
     * status=4 审核失败
     */
    Boolean textFlag = scanText(wmNews, (String) resultMap.get("content"));
    if(!textFlag){
      return;
    }
    //4.图片审核
    Boolean imageFlag = scanImage(wmNews, (List<String>) resultMap.get("imageList"));
    if(!imageFlag){
      return;
    }
    //5.审核通过，远程调用保存app端三剑客的接口
    ResponseResult result = saveArticleFromNews(wmNews);

    //6.修改wm_news状态=9
    if(result.getCode().equals(200)){
      wmNews.setArticleId(Long.valueOf(result.getData().toString()));
      updateWmNews(wmNews, (short) 9,"审核发布成功");
    }
  }

  /**
   * 抽取的第五个方法，保存三剑客
   * @param wmNews
   */
  private ResponseResult saveArticleFromNews(WmNews wmNews) {
    ArticleDto dto=new ArticleDto();
    BeanUtils.copyProperties(wmNews,dto);
    //作者id和name
    dto.setAuthorId(wmNews.getUserId().longValue());
    WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
    dto.setAuthorName(wmUser.getName());

    //频道id和name
    dto.setChannelId(wmNews.getChannelId());
    WmChannel wmChannel = wmChannelMapper.selectById(dto.getChannelId());
    dto.setChannelName(wmChannel.getName());

    //布局
    dto.setLayout(wmNews.getType());

    //创建时间
    dto.setCreatedTime(new Date());

    //设置行为数量默认为0
    dto.setViews(0);
    dto.setLikes(0);
    dto.setComment(0);
    dto.setCollection(0);

    ResponseResult result = apArticleFeignClient.save(dto);
    return  result;
  }

  /**
   * 抽取的第四个方法，审核图片
   * @param wmNews
   * @param imageList 图片地址集合
   * @return
   */
  private Boolean scanImage(WmNews wmNews, List<String> imageList) {
    //初始化标识，true表示通过，false表示审核失败
    Boolean flag=true;

    if(imageList!=null && imageList.size()>0){

      //对图片进行去重操作
      imageList = imageList.stream().distinct().collect(Collectors.toList());

      for (String path : imageList) {
        //下载图片
        byte[] bytes = fileStorageService.downLoadFile(path);
        //调用百度云审核的接口
        Integer status = baiduImageScan.imageScan(bytes);
        if(status==2){
          //修改wm_news表
          updateWmNews(wmNews, (short) 2, "图片中可能包含不合规的内容");
          flag=false;
          break;
        }else if(status==3){
          //修改wm_news表
          updateWmNews(wmNews, (short) 3, "图片中可能包含疑似不合规的内容,请通过人工审核");
          flag=false;
          break;
        }else if(status==4){
          //修改wm_news表
          updateWmNews(wmNews, (short) 2, "图片中可能包含审核失败的内容");
          flag=false;
          break;
        }
      }
    }
    return flag;
  }

  /**
   * 抽取的第三个方法，审核文本内容
   * @param wmNews
   * @param content
   * @return
   */
  private Boolean scanText(WmNews wmNews, String content) {
    //初始化标识，true表示通过，false表示审核失败
    Boolean flag=true;
    //调用审核的接口
    Integer status = baiduTextScan.textScan(content);

    if(status==2){
      //修改wm_news表
      updateWmNews(wmNews, (short) 2, "内容中可能包含不合规的词汇");
      flag=false;
    }else if(status==3){
      //修改wm_news表
      updateWmNews(wmNews, (short) 3, "内容中可能包含疑似不合规的词汇,请通过人工审核");
      flag=false;
    }else if(status==4){
      //修改wm_news表
      updateWmNews(wmNews, (short) 2, "内容中可能包含审核失败的词汇");
      flag=false;
    }
    return flag;
  }

  /**
   * 抽取的方法，修改wm_news表
   * @param wmNews
   * @param status
   * @param message
   */
  private void updateWmNews(WmNews wmNews, short status, String message) {
    wmNews.setStatus(status);
    wmNews.setReason(message);
    wmNewsMapper.updateById(wmNews);
  }

  /**
   * 抽取的第一个方法，先抽取所有的文本和图片
   * @param wmNews
   * @return
   */
  private Map<String,Object> handleTextAndImages(WmNews wmNews) {
    //定义字符串和集合用来封装文章内容和图片
    StringBuilder sb=new StringBuilder();
    List<String > imageList=new ArrayList<>();

    String title= wmNews.getTitle();
    sb.append(title);

    String content = wmNews.getContent();
    List<Map> contentList = JSONArray.parseArray(content, Map.class);
    for (Map map : contentList) {
      //获取图片
      if(map.get("type").equals("image")){
        imageList.add((String) map.get("value"));
      }
      //获取内容
      if(map.get("type").equals("text")){
        sb.append((String) map.get("value"));
      }
    }
    //封装封面图片到imageList中
    String images = wmNews.getImages();
    if(images!=null){
      imageList.addAll(Arrays.asList(images.split(",")));
    }
    //封装数据
    Map<String,Object> resultMap=new HashMap<>();
    resultMap.put("content",sb.toString());
    resultMap.put("imageList",imageList);
    return resultMap;
  }
}